import { Injectable } from '../decorators/inject';
import { NFont, NFill, NBorder } from '../types/style.interface';
import { assign } from '../utils/assign';
import { Config } from './config';
import { TCellControlValue, TCellControl } from '../types/common.interface';



@Injectable('FullControl')
export class FullControl {
    constructor(protected conf: Config) {

    }
    protected getEndCellControl(type: 'row'|'col'|'full', position: number): TCellControl {
        const cellControls = this.conf.cellControls;
        // @ts-ignore
        let endCellControl: TCellControl = {
            type: type,
            position: position
        };
        if(cellControls.length > 0 && cellControls[cellControls.length - 1].type === type && cellControls[cellControls.length - 1].position === position) {
            endCellControl = cellControls.pop();
        }
        return endCellControl;
    }
    protected addCellControl(obj: any) {
        let findIndex = -1;
        for(let i = this.conf.cellControls.length - 1; i >=0; i--) {
            if(this.conf.cellControls[i].type !== obj.type) break;
            if(this.conf.cellControls[i].type === obj.type && this.conf.cellControls[i].position === obj.position) {
                findIndex = i;
            }
        }
        if(findIndex === -1) {
            this.conf.cellControls.push(obj);
        } else {
            let old = this.conf.cellControls[findIndex];
            this.conf.cellControls.splice(findIndex, 1);
            // @ts-ignore
            this.conf.cellControls.push(assign(old, obj));
        }
        // this.conf.cellControls.push(obj)
    }
    public setRowStyle(row: number, value: TCellControlValue, span: number = 1) {
        this.addCellControl({type: 'row', position: row, span: span, ...value});
    }
    public setColStyle(col: number, value: TCellControlValue, span: number = 1) {
        this.addCellControl({type: 'col', position: col, span: span, ...value});
    }

    public setFullStyle(value: TCellControlValue) {
        this.addCellControl({type: 'full', position: -1, ...value});
    }

    public getFillStyle(row: number, col: number, fill: NFill.IFill) {
        let styles = this.conf.cellControls
        .filter(item => {
            if(item.type === 'row' && item.position === row) {
                return true;
            }
            if(item.type === 'col' && item.position === col) {
                return true;
            }
            if(item.type === 'full') {
                return true;
            }
            return false;
        })
        .filter((item: any) => item.fill !== null && item.fill !== undefined);
        if(styles.length === 0) return fill;
        if(!fill) {
            // @ts-ignore
            return styles[styles.length - 1].fill;
        }
        // @ts-ignore
        return assign(styles[styles.length - 1].fill, fill);
    }
    public getBorderStyle(row: number, col: number, border: any ){
        let styles = this.conf.cellControls
        .filter(item => {
            if(item.type === 'row' && item.position === row) {
                return true;
            }
            if(item.type === 'col' && item.position === col) {
                return true;
            }
            if(item.type === 'full') {
                return true;
            }
            return false;
        })
        .filter((item: any) => item.border !== null && item.border !== undefined)
        // @ts-ignore
        .map(item => item.border);
        if(styles.length === 0) return border;
        // @ts-ignore
        return assign(...styles, border);
    }
    public getCellType(row: number, col: number, cellType: string|null|undefined ) {
        if(cellType) {
            return cellType;
        }
        let styles = this.conf.cellControls
        .filter(item => {
            if(item.type === 'row' && item.position === row) {
                return true;
            }
            if(item.type === 'col' && item.position === col) {
                return true;
            }
            if(item.type === 'full') {
                return true;
            }
            return false;
        })
        .filter((item: any) => item.cellType !== null && item.cellType !== undefined)
        if(styles.length === 0) return cellType;
        // @ts-ignore
        return styles[styles.length - 1].cellType;
    }
    public getCellFont(row: number, col: number, font: NFont.IFont) {
        let fonts = this.conf.cellControls
        .filter(item => {
            if(item.type === 'row' && item.position === row) {
                return true;
            }
            if(item.type === 'col' && item.position === col) {
                return true;
            }
            if(item.type === 'full') {
                return true;
            }
            return false;
        })
        .filter((item: any) => item.font !== null && item.font !== undefined).map((item: any) => item.font);
        fonts.unshift(this.conf.defaultFont);
        // @ts-ignore
        return assign(...fonts, font);
    }
}